package org.codeart.apipassenger.service;

import cn.hutool.core.util.StrUtil;
import org.codeart.apipassenger.remote.ServiceUserClient;
import org.codeart.apipassenger.remote.VerifyCodeClient;
import org.codeart.common.constant.IdentityEnum;
import org.codeart.common.constant.TokenEnum;
import org.codeart.common.util.R;
import org.codeart.common.dto.VerifyCodeDTO;
import org.codeart.common.response.TokenResponse;
import org.codeart.common.util.JwtUtils;
import org.codeart.common.util.RedisPrefixUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerificationCodeService {

    @Autowired
    private VerifyCodeClient verifyCodeClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ServiceUserClient serviceUserClient;

    /**
     * 生成验证码
     */
    public boolean generateCode(String phone) {
        R<Map<Object, Object>> r = verifyCodeClient.getCode(6);
        Map<Object, Object> data = r.getData();
        String numberCode = (String) data.get("numberCode");
        System.out.println("remote code : " + numberCode);

        String key = RedisPrefixUtil.generateKey(phone, IdentityEnum.PASSENGER.value());
        redisTemplate.opsForValue().set(key, numberCode, 5, TimeUnit.MINUTES);

        // 调用短信服务，发送短信
        return true;
    }

    /**
     * 校验手机号
     *
     * @param phone 手机号
     * @param code  验证码
     */
    public TokenResponse checkCode(String phone, String code) {
        if (StrUtil.isEmpty(code)) {
            return null;
        }

        String key = RedisPrefixUtil.generateKey(phone, IdentityEnum.PASSENGER.value());
        String correctCode = redisTemplate.opsForValue().get(key);

        if (!code.trim().equals(correctCode)) {
            return null;
        }

        VerifyCodeDTO verifyCodeDTO = new VerifyCodeDTO();
        verifyCodeDTO.setPassengerPhone(phone);
        serviceUserClient.login(verifyCodeDTO);

        // 颁发令牌，不可以使用魔法值
        String accessToken = JwtUtils.generateToken(phone, IdentityEnum.PASSENGER.value(), TokenEnum.ACCESS_TOKEN.value());
        String refreshToken = JwtUtils.generateToken(phone, IdentityEnum.PASSENGER.value(), TokenEnum.REFRESH_TOKEN.value());


        // 把token存入redis，30天有效期
        String accessTokenKey = RedisPrefixUtil.generateTokenKey(phone, IdentityEnum.PASSENGER.value(), TokenEnum.ACCESS_TOKEN.value());
        redisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.DAYS);

        String refreshTokenKey = RedisPrefixUtil.generateTokenKey(phone, IdentityEnum.PASSENGER.value(), TokenEnum.REFRESH_TOKEN.value());
        redisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 31, TimeUnit.DAYS);

        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken).setRefreshToken(refreshToken);
        return tokenResponse;
    }

}
